/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package controller;

import com.google.gson.Gson;
import local.RoleFacadeLocal;
import local.SystemUserFacadeLocal;
import java.io.IOException;
import java.security.MessageDigest;
import java.util.ArrayList;
import javax.ejb.EJB;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import model.Role;
import model.SystemUser;
import util.AutoGeneratedPassword;
import util.Email;
import util.JsonReturnDropDown;
import util.JsonReturnMsg;
import util.JsonReturnTable;

/**
 *
 * @author karennyq
 */
@WebServlet(name = "SystemUser", urlPatterns = {"/SystemUserServlet"})
public class SystemUserServlet extends HttpServlet {

    /** 
     * Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @EJB
    SystemUserFacadeLocal systemUserFacade;
    @EJB
    RoleFacadeLocal roleFacade;
    Gson gson = new Gson();
    private String json;

    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        String action = request.getParameter("action");

        try {
            if (action.equals("loadTable")) {
                loadTable(request, response);

            } else if (action.equals("loadRoleDropDown")) {
                loadRoleDropDown(request, response);

            } else if (action.equals("loadUpdateRoleDropDown")) {
                loadUpdateRoleDropDown(request, response);

            } else if (action.equals("createSysUser")) {
                createSysUser(request, response);

            } else if (action.equals("deleteSysUser")) {
                deleteSysUser(request, response);

            } else if (action.equals("resetPwd")) {
                resetPwd(request, response);

            } else if (action.equals("updateSystemUser")) {
                updateSystemUser(request, response);

            } else if (action.equals("changePwd")) {
                changePwd(request, response);

            } else if (action.equals("checkOldPwd")) {
                checkOldPwd(request, response);
            }

        } catch (Exception ex) {
            json = gson.toJson(new JsonReturnMsg("Error", ex.getMessage(), "error"));
            response.getWriter().println(json);
        } finally {
            response.getWriter().close();
        }
    }

    private void loadTable(HttpServletRequest request, HttpServletResponse response) throws Exception {
        int page = (request.getParameter("page") != null) ? Integer.parseInt(request.getParameter("page")) : 1;
        int rows = (request.getParameter("rows") != null) ? Integer.parseInt(request.getParameter("rows")) : 10;
        String sort = (request.getParameter("sort") != null) ? request.getParameter("sort") : "sys_user_id";
        String order = (request.getParameter("order") != null) ? request.getParameter("order") : "asc";

        ArrayList<SystemUser> sysUserList = new ArrayList(systemUserFacade.findAllSysUser(page, rows, sort, order));
        for (SystemUser su : sysUserList) {
            su.setRole_name();
            su.setRole_id();
        }

        int totalRecord = systemUserFacade.countAllSysUser(page, rows, sort, order);
        json = gson.toJson(new JsonReturnTable(totalRecord + "", sysUserList));
        response.getWriter().println(json);
    }

    private void loadRoleDropDown(HttpServletRequest request, HttpServletResponse response) throws Exception {
        ArrayList<Role> roleList = new ArrayList(roleFacade.findAllRoles());

        ArrayList<JsonReturnDropDown> roleNameList = new ArrayList();
        for (Role r : roleList) {
            if (!r.getRole_name().equals("Public User")) {
                if (!r.getRole_name().equals("Registered User")) {

                    JsonReturnDropDown dd = new JsonReturnDropDown();
                    dd.setId(Integer.parseInt(r.getRole_id() + ""));
                    dd.setText(r.getRole_name());

                    roleNameList.add(dd);
                }
            }
        }
        json = gson.toJson(roleNameList);
        response.getWriter().println(json);
    }

    private void loadUpdateRoleDropDown(HttpServletRequest request, HttpServletResponse response) throws Exception {
        ArrayList<Role> roleList = new ArrayList(roleFacade.findAllRoles());

        ArrayList<JsonReturnDropDown> roleNameList = new ArrayList();
        for (Role r : roleList) {
            if (!r.getRole_name().equals("Public User")) {
                if (!r.getRole_name().equals("Registered User")) {

                    JsonReturnDropDown dd = new JsonReturnDropDown();
                    dd.setId(Integer.parseInt(r.getRole_id() + ""));
                    dd.setText(r.getRole_name());

//                    if (r.getRole_id() == 1) {
//                        dd.setSelected(true);
//                    }

                    roleNameList.add(dd);
                }
            }
        }
        json = gson.toJson(roleNameList);
        response.getWriter().println(json);
    }

    private void createSysUser(HttpServletRequest request, HttpServletResponse response) throws Exception {
        String user_name = request.getParameter("user_name");
        String user_email = request.getParameter("user_email");
        String user_role_id = request.getParameter("user_role");
        Long role_id = Long.parseLong(user_role_id);

        boolean exist = systemUserFacade.checkForExistence(user_email);
        if (exist == true) {
            json = gson.toJson(new JsonReturnMsg("New System User", "Email already exist!", "error"));
        } else {
            Role r = roleFacade.findRole(role_id);

            //System Auto-Generated Password
            String generatedPwd = new AutoGeneratedPassword().getNext();
            //String generatedPwd = Long.toHexString(Double.doubleToLongBits(Math.random())).toString();

            //Hash the auto-generated password
            MessageDigest md = MessageDigest.getInstance("MD5");
            md.update(generatedPwd.getBytes());
            byte byteData1[] = md.digest();
            //convert the byte to hex format method 1
            StringBuilder sb1 = new StringBuilder();
            for (int i = 0; i < byteData1.length; i++) {
                sb1.append(Integer.toString((byteData1[i] & 0xff) + 0x100, 16).substring(1));
            }
            String hashedEmpPassword = sb1.toString();

            SystemUser su = new SystemUser();
            su.setName(user_name);
            su.setEmail(user_email);
            su.setPassword(hashedEmpPassword);
            su.setRole(r);

            boolean status = systemUserFacade.createSysUser(su);
            if (status == true) {
                try {
                    Email emailManager = new Email();
                    boolean emailStatus = emailManager.emailUserPassword(user_email, generatedPwd, user_name);
                    if (emailStatus == true) {
                        json = gson.toJson(new JsonReturnMsg("New System User", "System User created!<br/>A notification email has been sent to the user.", "info"));
                    } else {
                        json = gson.toJson(new JsonReturnMsg("New System User", "System User created!<br/>Notification email was unable to be send out. Missing Email Template!", "email-error"));
                    }

                } catch (Exception e) {
                    json = gson.toJson(new JsonReturnMsg("New System User", "System User created!<br/>Notification email was unable to be send out.<br/> Error: " + e.getMessage(), "info"));
                }
                //request.getRequestDispatcher("/index.jsp").forward(request, response);
            } else {
                json = gson.toJson(new JsonReturnMsg("New System User", "System unable to create!", "error"));
            }
        }
        response.getWriter().println(json);
    }

    private void deleteSysUser(HttpServletRequest request, HttpServletResponse response) throws Exception {
        String sys_user_id = (request.getParameter("sys_user_id") != null) ? request.getParameter("sys_user_id") : "";
        if (!sys_user_id.equals("")) {
            Long user_id = Long.parseLong(sys_user_id);
            boolean exist = systemUserFacade.checkForExistence(user_id);
            if (exist == true) {
                systemUserFacade.deleteSysUser(user_id);
                json = gson.toJson(new JsonReturnMsg("Delete System User", "System User deleted", "info"));
            } else {
                json = gson.toJson(new JsonReturnMsg("Delete System User", "System User does not exist", "error"));
            }
        } else {
            json = gson.toJson(new JsonReturnMsg("Delete System User", "System User does not exist", "error"));
        }
        response.getWriter().println(json);
    }

    private void resetPwd(HttpServletRequest request, HttpServletResponse response) throws Exception {
        String sys_user_id = (request.getParameter("sys_user_id") != null) ? request.getParameter("sys_user_id") : "";
        if (!sys_user_id.equals("")) {
            Long user_id = Long.parseLong(sys_user_id);
            boolean exist = systemUserFacade.checkForExistence(user_id);
            if (exist == true) {
                //System Auto-Generated Password
                String generatedPwd = new AutoGeneratedPassword().getNext();
                //String generatedPwd = Long.toHexString(Double.doubleToLongBits((int)(Math.random()*100))).toString();

                //Hash the auto-generated password
                MessageDigest md = MessageDigest.getInstance("MD5");
                md.update(generatedPwd.getBytes());
                byte byteData1[] = md.digest();
                //convert the byte to hex format method 1
                StringBuilder sb1 = new StringBuilder();
                for (int i = 0; i < byteData1.length; i++) {
                    sb1.append(Integer.toString((byteData1[i] & 0xff) + 0x100, 16).substring(1));
                }
                String hashedEmpPassword = sb1.toString();

                SystemUser su = systemUserFacade.resetPwd(user_id, hashedEmpPassword);
                try {
                    Email emailManager = new Email();
                    boolean emailStatus = emailManager.emailUserNewPassword(su.getEmail(), generatedPwd, su.getName());
                    if (emailStatus == true) {
                        json = gson.toJson(new JsonReturnMsg("Reset Password", "Password Resetted<br/>A notification email has been sent to the user.", "info"));
                    } else {
                        json = gson.toJson(new JsonReturnMsg("Reset Password", "Password Resetted<br/>Notification email was unable to be send out. Missing Email Template!", "error"));
                    }

                } catch (Exception e) {
                    json = gson.toJson(new JsonReturnMsg("Reset Password", "Password Resetted<br/>Notification email was unable to be send out.<br/> Error: " + e.getMessage(), "error"));
                }
            } else {
                json = gson.toJson(new JsonReturnMsg("Reset Password", "System User does not exist", "error"));
            }
        } else {
            json = gson.toJson(new JsonReturnMsg("Reset Password", "System User does not exist", "error"));
        }
        response.getWriter().println(json);
    }

    private void updateSystemUser(HttpServletRequest request, HttpServletResponse response) throws Exception {
        String user_email = request.getParameter("updated_email");
        String user_name = request.getParameter("updated_name");
        String user_role_name = request.getParameter("updated_role");
        String sys_user_id = (request.getParameter("sys_user_id") != null) ? request.getParameter("sys_user_id") : "";

        if (user_email.isEmpty() || user_name.isEmpty() || user_role_name.isEmpty()) {
            json = gson.toJson(new JsonReturnMsg("Edit System User", "All fields are required", "error"));
        } else {
            if (!sys_user_id.equals("")) {
                Long user_id = Long.parseLong(sys_user_id);

                //Long role_id = Long.parseLong(user_role_name);

                boolean exist = systemUserFacade.checkForExistence(user_id);
                if (exist == true) {
                    SystemUser su = systemUserFacade.getSysUser(user_id);
                    boolean emailExist = true;
                    if (!user_email.equals(su.getEmail())) {
                        emailExist = systemUserFacade.checkForExistence(user_email);
                    } else {
                        emailExist = false;
                    }
                    if (emailExist == false) {
                        Role r = roleFacade.findRole(user_role_name);
                        systemUserFacade.updateSysUser(user_id, user_email, r, user_name);
                        json = gson.toJson(new JsonReturnMsg("Edit System User", "System User updated", "info"));
                    } else {
                        json = gson.toJson(new JsonReturnMsg("Edit System User", "Email already exist!", "error"));
                    }
                } else {
                    json = gson.toJson(new JsonReturnMsg("Edit System User", "System User does not exist", "error"));
                }
            } else {
                json = gson.toJson(new JsonReturnMsg("Edit System User", "System User does not exist", "error"));
            }
        }
        response.getWriter().println(json);
    }

    private void changePwd(HttpServletRequest request, HttpServletResponse response) throws Exception {
        String new_pwd = request.getParameter("new_password");
        String old_pwd = request.getParameter("old_password");
        HttpSession session = request.getSession(true);
        SystemUser sysUser = (SystemUser) session.getAttribute("sysUser");

        //Hash the auto-generated password
        MessageDigest md = MessageDigest.getInstance("MD5");
        md.update(old_pwd.getBytes());
        byte byteData1[] = md.digest();
        //convert the byte to hex format method 1
        StringBuffer sb1 = new StringBuffer();
        for (int i = 0; i < byteData1.length; i++) {
            sb1.append(Integer.toString((byteData1[i] & 0xff) + 0x100, 16).substring(1));
        }
        String hashedOldPassword = sb1.toString();

        if (hashedOldPassword.equals(sysUser.getPassword())) {
            //Hash the auto-generated password
            md = MessageDigest.getInstance("MD5");
            md.update(new_pwd.getBytes());
            byteData1 = md.digest();
            //convert the byte to hex format method 1
            sb1 = new StringBuffer();
            for (int i = 0; i < byteData1.length; i++) {
                sb1.append(Integer.toString((byteData1[i] & 0xff) + 0x100, 16).substring(1));
            }
            String hashedNewPassword = sb1.toString();

            sysUser.setPassword(hashedNewPassword);
            sysUser = systemUserFacade.updateSysUser(sysUser);
            session.setAttribute("sysUser", sysUser);
            json = gson.toJson(new JsonReturnMsg("Update System User", "Password updated successfully!", "info"));

        } else {
            json = gson.toJson(new JsonReturnMsg("Update System User", "Your old password does not match!", "error"));
        }
        response.getWriter().println(json);
    }

    private void checkOldPwd(HttpServletRequest request, HttpServletResponse response) throws Exception {
        String old_pwd = request.getParameter("old_password");
        HttpSession session = request.getSession(true);
        SystemUser sysUser = (SystemUser) session.getAttribute("sysUser");

        //Hash the auto-generated password
        MessageDigest md = MessageDigest.getInstance("MD5");
        md.update(old_pwd.getBytes());
        byte byteData1[] = md.digest();
        //convert the byte to hex format method 1
        StringBuilder sb1 = new StringBuilder();
        for (int i = 0; i < byteData1.length; i++) {
            sb1.append(Integer.toString((byteData1[i] & 0xff) + 0x100, 16).substring(1));
        }
        String hashedOldPassword = sb1.toString();

        if (hashedOldPassword.equals(sysUser.getPassword())) {
            json = gson.toJson(new JsonReturnMsg("Update System User", "Your old password match!", "info"));

        } else {
            json = gson.toJson(new JsonReturnMsg("Update System User", "Your old password does not match!", "error"));
        }

        response.getWriter().println(json);
    }

    // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
    /** 
     * Handles the HTTP <code>GET</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /** 
     * Handles the HTTP <code>POST</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /** 
     * Returns a short description of the servlet.
     * @return a String containing servlet description
     */
    @Override
    public String getServletInfo() {
        return "Short description";
    }// </editor-fold>
}
